/**
 * Created with IntelliJ IDEA.
 * User: liulinhui
 * Date: 18-10-9
 * Time: 上午11:58
 * Description: sign.js
 */
import keys from './keys'
import convert from './convert'
import ed2curve from 'ed2curve'

/**
 * 加密信息
 * @param message 原始信息
 * @param secret 密码
 * @returns {*}
 */
function signMessageWithSecret(message, secret) {
  let msg = global.naclInstance.encode_utf8(message);
  let keyPair = keys.getRawPrivateAndPublicKeyFromSecret(secret);

  let signedMessage = global.naclInstance.crypto_sign(msg, keyPair.privateKey);
  return convert.bufferToHex(signedMessage);
}

/**
 * 解密信息
 * @param signedMessage 密文
 * @param publicKey
 */
function verifyMessageWithPublicKey(signedMessage, publicKey) {
  let signedMessageBytes = convert.hexToBuffer(signedMessage);
  let publicKeyBytes = convert.hexToBuffer(publicKey);

  if (publicKeyBytes.length !== 32) {
    throw new Error('Invalid publicKey, expected 32-byte publicKey');
  }

  let openSignature = global.naclInstance.crypto_sign_open(signedMessageBytes, publicKeyBytes);

  if (openSignature) {
    return global.naclInstance.decode_utf8(openSignature);
  } else {
    throw new Error('Invalid signature publicKey combination, cannot verify message');
  }
}

function convertPublicKeyEd2Curve(publicKey) {
  return ed2curve.convertPublicKey(publicKey);
}

function convertPrivateKeyEd2Curve(privateKey) {
  return ed2curve.convertSecretKey(privateKey);
}

function encryptMessageWithSecret(message, secret) {
  let privateKey = keys.getRawPrivateAndPublicKeyFromSecret(secret).privateKey;
  let publicKeyBytes = keys.getRawPrivateAndPublicKeyFromSecret(secret).publicKey;
  message = global.naclInstance.encode_utf8(message);

  let nonce = global.naclInstance.crypto_box_random_nonce();
  let packet = global.naclInstance.crypto_box(message, nonce, convertPublicKeyEd2Curve(publicKeyBytes), convertPrivateKeyEd2Curve(privateKey));

  let nonceHex = convert.bufferToHex(nonce);
  let encryptedMessage = convert.bufferToHex(packet);

  return {
    nonce: nonceHex,
    encryptedMessage: encryptedMessage
  };
}

function decryptMessageWithSecret(packet, nonce, secret) {
  let privateKey = keys.getRawPrivateAndPublicKeyFromSecret(secret).privateKey;
  let publicKeyBytes = keys.getRawPrivateAndPublicKeyFromSecret(secret).publicKey;
  let packetBytes = convert.hexToBuffer(packet);
  let nonceBytes = convert.hexToBuffer(nonce);

  let decoded = global.naclInstance.crypto_box_open(packetBytes, nonceBytes,
    convertPublicKeyEd2Curve(publicKeyBytes), convertPrivateKeyEd2Curve(privateKey));

  return global.naclInstance.decode_utf8(decoded);
}

export default {
  verifyMessageWithPublicKey: verifyMessageWithPublicKey,
  signMessageWithSecret: signMessageWithSecret,
  encryptMessageWithSecret: encryptMessageWithSecret,
  decryptMessageWithSecret: decryptMessageWithSecret,
  convertPublicKeyEd2Curve: convertPublicKeyEd2Curve,
  convertPrivateKeyEd2Curve: convertPrivateKeyEd2Curve
};
